/*
 * HttpPostDevice.cpp
 *
 *  Created on: 2012-11-7
 *      Author: minhua
 */

#include "HttpPostDevice.h"
#include <QtDebug>
#include "../utils/TConverter.h"
#include <QBuffer>
#include <QFileInfo>

HttpPostDevice::HttpPostDevice(QHash<QString, QVariant> variables, QHash<QString, QString> files, QObject *parent) : QIODevice(parent)
{
	_totalContentSize = 0;

	QString split = "---------------------------7dc92720f6c";

	QHashIterator<QString, QVariant> iterator(variables);
	while(iterator.hasNext())
	{
		QString key = iterator.next().key();
		_variablesContent.append("--" + split + "\r\n");
		_variablesContent.append("Content-Disposition: ");
		_variablesContent.append("form-data; name=\"" + key + "\"\r\n");
		_variablesContent.append("\r\n");

		QVariant value = variables.value(key);
		switch(value.type())
		{
		case QVariant::Int:
			_variablesContent.append(QString::number(value.toInt()));
			break;
		case QVariant::Double:
			_variablesContent.append(QString::number(value.toDouble()));
			break;
		case QVariant::String:
			_variablesContent.append(value.toString().toUtf8());
			break;
		case QVariant::Date:
			_variablesContent.append(TConverter::dateToString(value.toDate()));
			break;
		case QVariant::Time:
			_variablesContent.append(TConverter::timeToString(value.toTime()));
			break;
		case QVariant::DateTime:
			_variablesContent.append(TConverter::datetimeToString(value.toDateTime()));
			break;
		default:
			break;
		}
		_variablesContent.append("\r\n");
	}
	_deviceList.append(new QBuffer(&_variablesContent));
	_deviceList.last()->open(QIODevice::ReadOnly);

	QHashIterator<QString, QString> fileIterator(files);
	while(fileIterator.hasNext())
	{
		QString key = fileIterator.next().key();
		PostFileContent *postFile = new PostFileContent();
		postFile->FileHandler.setFileName(files.value(key));
		if(postFile->FileHandler.exists() && postFile->FileHandler.open(QFile::ReadOnly))
		{

			QFileInfo fileInfo(files.value(key));
			postFile->TopContent.append("--" + split + "\r\n");
			postFile->TopContent.append("Content-Disposition: ");
			postFile->TopContent.append("form-data; name=\""+key+"\"; filename=\""+fileInfo.fileName().toUtf8()+"\"\r\n");
			//content.append("Content-Transfer-Encoding: binary\r\n");
			postFile->TopContent.append("Content-Type: application/x-zip-compressed\r\n");
			postFile->TopContent.append("\r\n");
			_deviceList.append(new QBuffer(&(postFile->TopContent)));
			_deviceList.last()->open(QIODevice::ReadOnly);

			_deviceList.append(&(postFile->FileHandler));

			postFile->BottomContent.append("\r\n");
			_deviceList.append(new QBuffer(&(postFile->BottomContent)));
			_deviceList.last()->open(QIODevice::ReadOnly);

			this->_fileContentList.append(postFile);
		}
	}

	_endContent.append("--" + split + "--");
	_endContent.append("\r\n");
	_deviceList.append(new QBuffer(&_endContent));
	_deviceList.last()->open(QIODevice::ReadOnly);

	for(int i=1; i<=_deviceList.size(); i++)
	{
		_totalContentSize += _deviceList.at(i-1)->size();
	}

	_myPos = 0;
}

HttpPostDevice::~HttpPostDevice()
{
	// TODO Auto-generated destructor stub
}

qint64 HttpPostDevice::size() const
{
	qDebug() << "HttpPostDevice::size" << _totalContentSize;
	return _totalContentSize;
}

qint64 HttpPostDevice::readData(char *data, qint64 maxlen)
{
	//qDebug() << "HttpPostDevice::readData" << maxlen << _myPos << this->atEnd() << this->bytesAvailable() << this->isSequential();

	if(_totalContentSize<=0)
		return -1;

	if(_myPos>=_totalContentSize)
		return -1;

	if(maxlen<=0)
		return maxlen;

	qint64 readPos = _myPos;
	qint64 totalReadLen = 0;
	qint64 prevDeviceEndPos = 0;
	for(int i=1; i<=_deviceList.size(); i++)
	{
		QIODevice *_device = _deviceList.at(i-1);
		qint64 deviceEndPos = prevDeviceEndPos+_device->size();
		if(prevDeviceEndPos<=readPos && readPos<deviceEndPos)
		{
			_device->seek(readPos-prevDeviceEndPos);
			if(!_device->atEnd())
			{
				qint64 readLen = _device->read(data+totalReadLen, maxlen);
				totalReadLen+=readLen;
				if(readLen==maxlen)
				{
					return totalReadLen;
				}
				else
				{
					readPos+=readLen;
					maxlen-=readLen;
				}
			}
		}
		if(maxlen<=0)
			break;
		prevDeviceEndPos = deviceEndPos;
	}
	_myPos += totalReadLen;
	qDebug() << "totalReadLen " << totalReadLen;
	return totalReadLen;
}

qint64 HttpPostDevice::writeData(const char *data, qint64 len)
{
	qDebug() << "HttpPostDevice::writeData";
}

qint64 HttpPostDevice::bytesAvailable() const
{
	qDebug() << "HttpPostDevice::bytesAvailable";
	return _totalContentSize - _myPos;
}

bool HttpPostDevice::atEnd() const
{
	qDebug() << "HttpPostDevice::atEnd";
	return _myPos>=_totalContentSize;
}
